import re
import collections
import numpy as np
import jieba
import os
from nltk import ngrams
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet
from nltk import pos_tag

#第一步功能一:统计词频
def all_layout(str):
    target=open(str,encoding='utf-8')
    novel=target.read()
    target.close()
    sp=re.compile(u'\t|\n|\.|-|:|;|\(|\?|\'|,|!')
    novel=re.sub(sp,' ',novel)
    novel=novel.lower()
    novel_done=novel.split()
    word_count=collections.Counter(novel_done)
    print(word_count)

#第一步功能三:统计词频，输出排行前几的词汇
def max_layout(str,m):
    target=open(str,encoding='utf-8')
    novel=target.read()
    target.close()
    sp=re.compile(u'\t|\n|\.|-|:|;|\(|\?|\'|,|!')
    novel=re.sub(sp,' ',novel)
    novel=novel.lower()
    novel_done=novel.split()
    word_count=collections.Counter(novel_done)
    word_count_top=word_count.most_common(int(m))
    print(word_count_top)

#第二步功能四:对文件aim进行词频统计，该统计需要去除某些词汇，这些词汇被写在另一个文件stop中
def stop_words_layout(aim,stop):
    target=open(aim,encoding='utf-8')
    novel=target.read()
    target.close()
    sp=re.compile(u'\t|\n|\.|-|:|;|\(|\?|\'|,|!')
    novel=re.sub(sp,' ',novel)
    novel=novel.lower()
    novel_done=novel.split()
    stop_words_done=[]
    stop_words_well_done=[]
    novel_well_done=[]
    words=open(stop,encoding='utf-8')
    stop_words=words.read()
    words.close()
    stop_words=re.sub(r'\n+',' ',stop_words)
    stop_words=jieba.cut(stop_words,cut_all=False)
    for m in stop_words:
        stop_words_done.append(m)
    for m in stop_words_done:
        if m !=' ':
            stop_words_well_done.append(m)
    for j in novel_done:
        if j not in stop_words_well_done:
            novel_well_done.append(j)
    word_count=collections.Counter(novel_well_done)
    print(word_count)

#第三步功能五:对短语进行计数，使用者可指定短语长度、输出排行前几的短语
def phrases(location,lens,m):
    target=open(location,encoding='utf-8')
    novel=target.read()
    target.close()
    sp=re.compile(u'\t|\n|\.|-|:|;|\(|\?|\'|,|!')
    novel=re.sub(sp,' ',novel)
    novel=novel.lower()
    novel_done=ngrams(novel.split(),lens)
    word_count=collections.Counter(novel_done)
    word_count_top=word_count.most_common(m)
    print(word_count_top)

#功能六:将动词的各时态归一之后进行动词词频统计
def choose_verb(aim):
    target=open(aim,encoding='utf-8')   #主函数传入文件路径，以utf-8格式打开文件
    novel=target.read()
    target.close()
    novel_verb=[]
    wnl=WordNetLemmatizer()             #将WordNetLemmatizer实例化
    sp=re.compile(u'\t|\n|\.|-|:|;|\(|\?|\'|,|!')       #创建分割标记变量sp
    novel=re.sub(sp,' ',novel)                          #以sp中的符号为对象，将这些对象替换成空格，进行替换的目标为novel
    novel=novel.lower()                 #将替换为空格的novel全部小写化
    novel_done=novel.split()            #将novel切分为列表novel_done,split()默认以空格作为切分条件
    for word,tag in pos_tag(novel_done):
        if tag.startswith('VB'):
            novel_verb.append(wnl.lemmatize(word,pos='v'))
    word_count=collections.Counter(novel_verb)
    print(word_count)
'''由于lemmitize方法的第一个参数必须是字符串或只含一个元素的元组而不能是列表（列表无法HASH化），同时需要一个变量来判断是否
    为动词，所以用两个变量遍历pos_tag(novel_done)。pos_tag函数可以将一个列表变成如下形式：[(word,word_tag),(,),...]，即一个
    包含若干元组的列表，其中每个元组的第一个值是原来列表中的字符串，每个元组的第二个值为这个字符串的词性，当tag值包含vb时，其
    对应的word是动词，对这个word调用wnl.lemmatize(),设置pos参数为v，将这个word归一，并将归一后的word添加到列表word_verb中，再对word_verb进行计数操作'''

#调试函数:作为编写代码时进行调试的函数，没有任何参考意义
def test():
    wrp=WordNetLemmatizer()
    tuple1=('hello','told','speak','walking')
    print(wrp.lemmatize(tuple1[1]),pos='v')



#主函数：某种意义上的主函数
the_type=input()
if the_type=='-f':
    aim_direct=input("输入文件路径:")
    all_layout(aim_direct)

#第一步功能二：对目标文件夹下所有文件进行词频统计
if the_type=='-d':
    aim=input("输入文件夹路径:")
    for file_name in os.listdir(aim):
        all_layout(aim+file_name)
        print('\n')

if the_type=='-n':
    aim_direct=input("输入文件路径:")
    n=int(input("输入limit个数:"))
    max_layout(aim_direct,n)

if the_type=='-x':
    aim_direct=input("输入文件路径:")
    stop_list=input("输入屏蔽词文件路径")
    stop_words_layout(aim_direct,stop_list)

if the_type=='-p':
    aim_direct=input("输入文件路径:")
    lens=int(input("输入短语长度:"))
    m=int(input("要输出递减排序的前几个短语？"))
    phrases(aim_direct,lens,m)

if the_type=='-v':
    aim_direct=input("输入文件路径:")
    choose_verb(aim_direct)

if the_type=='test':
    test()